package com.xgure.aop;

import com.xgure.annotation.Autofill;
import com.xgure.constant.AutofillConstant;
import com.xgure.enumerator.AutofillEnum;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Slf4j
@Aspect
@Component
public class AutofillAspect {

    // 定义切点，匹配所有被@Autofill注解的方法
    @Pointcut("execution(* com.xgure.mapper..*.*(..)) && @annotation(com.xgure.annotation.Autofill)")
    public void autofillPointcut() {
    }

    /**
     * 对插入数据进行创建时间或更新时间的自动填充
     */
    @Before("autofillPointcut()")
    public void autofill(JoinPoint joinPoint) {
        log.info("开始进行自动填充");
        // 获取注解中的参数值
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Autofill anno = method.getAnnotation(Autofill.class);

        if (anno != null) {
            AutofillEnum value = anno.value();
            Object[] args = joinPoint.getArgs();
            if (args != null && args.length > 0) {
                // 获取实体对象
                Object obj = args[0];
                LocalDateTime now = LocalDateTime.now();
                if (value == AutofillEnum.INSERT) {
                    // 插入操作
                    try {
                        obj.getClass().getDeclaredMethod(AutofillConstant.SET_CREATE_TIME, LocalDateTime.class).invoke(obj, now);
                        obj.getClass().getDeclaredMethod(AutofillConstant.SET_UPDATE_TIME, LocalDateTime.class).invoke(obj, now);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    // 更新操作
                    try {
                        obj.getClass().getDeclaredMethod(AutofillConstant.SET_UPDATE_TIME, LocalDateTime.class).invoke(obj, now);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}
